package com.usian.comment.service.impl;


import com.usian.comment.feign.UserFeign;
import com.usian.comment.service.CommentService;
import com.usian.common.exception.CatchCustomException;
import com.usian.common.exception.code.UserStatusCode;
import com.usian.model.comment.dtos.CommentDto;
import com.usian.model.comment.dtos.CommentLikeDto;
import com.usian.model.comment.dtos.CommentSaveDto;
import com.usian.model.comment.pojos.ApComment;
import com.usian.model.comment.pojos.ApCommentLike;
import com.usian.model.comment.vos.ApCommentVo;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.user.pojos.ApUser;
import com.usian.utils.common.SnowflakeIdWorker;
import com.usian.utils.threadlocal.AppThreadLocalUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        if(dto==null){
            CatchCustomException.catchs(UserStatusCode.PARAM_FAIL,"参数非法");
        }
        if (dto.getContent() != null && dto.getContent().length() > 140) {
            CatchCustomException.catchs(UserStatusCode.PARAM_FAIL,"评论内容不能超过140字");
        }

        //用户登录
        ApUser apUser =  AppThreadLocalUtils.getUser();
        if(apUser==null){
            //没登录
            CatchCustomException.catchs(UserStatusCode.PARAM_FAIL,"用户没有登录");
        }
        apUser =  userFeign.findUserById(apUser.getId());
        if(apUser == null){
            CatchCustomException.catchs(UserStatusCode.PARAM_FAIL,"评论用户账户出现问题");
        }
        ApComment apComment = new ApComment();
        // idworker
        apComment.setId(snowflakeIdWorker.nextId()+"");
        apComment.setAuthorId(apUser.getId());
        apComment.setAuthorName(apUser.getName());
        apComment.setContent(dto.getContent());
        apComment.setEntryId(dto.getArticleId());
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        apComment.setImage(apUser.getImage());
        apComment.setLikes(0); // 喜欢
        apComment.setReply(0); // 回复数
        apComment.setType((short) 0); //文章
        apComment.setFlag((short) 0); //默认普通评论
        mongoTemplate.insert(apComment);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //1.检查参数
        if (dto.getCommentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // 获取登录用户信息
        //2.判断是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(),ApComment.class);
        // 保存点赞数据
        if (apComment != null && dto.getOperation() == 0) {
            //点赞  apcomment + 1  新增 likes
            apComment.setLikes(apComment.getLikes()+1);
            mongoTemplate.save(apComment);

            // 先查询当前用户是否已经对当前评论点过赞了
            Long count =  mongoTemplate.count(new Query(Criteria.where("authorId").is(user.getId()).and("commentId").is(apComment.getId())),ApCommentLike.class);
            if(count>0){
                //已经点过了
                return null;
            }
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(user.getId());
            apCommentLike.setCommentId(apComment.getId());
            apCommentLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentLike);
        }else if(apComment != null && dto.getOperation() == 1){
            //取消点赞 -1  删除
            if(apComment.getLikes()>=1){
                apComment.setLikes(apComment.getLikes()-1);
            }
            mongoTemplate.save(apComment);

            // 2条件  作者id  评论id
            mongoTemplate.remove(new Query(Criteria.where("authorId").is(user.getId()).and("commentId").is(apComment.getId())),ApCommentLike.class);
        }
        //5.数据返回
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("likes",apComment.getLikes());
        return ResponseResult.okResult(resultMap);
    }

    @Override
    public ResponseResult findByArticleId(CommentDto dto) {
        //1.检查参数
        if(dto.getArticleId() == null){
            //文章Id不能为空
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        dto.setMinDate(new Date());
        // 设置初始 加载更多页数
        int size = 10;
        Query query = Query.query(Criteria.where("entryId").is(dto.getArticleId()).and("createdTime").lt(dto.getMinDate()));
        //设置每页展示数
        query.limit(size);
        //倒序展示
        query.with(Sort.by(Sort.Order.desc("createdTime")));
        //query.with(Sort.by(Sort.Direction.DESC,"createdTime"));
        List<ApComment> list = mongoTemplate.find(query, ApComment.class);

        //3.1 用户未登录 加载数据
        ApUser user = AppThreadLocalUtils.getUser();
        if(user== null){
            return ResponseResult.okResult(list);
        }
        // 根据登录用户和文章Id 查询点赞信息
        // 通过流式编程  单独获取评论Id
        List<String> idList  = list.stream().map(x -> x.getId()).collect(Collectors.toList());
        Query query1 = Query.query(Criteria.where("commentId").in(idList).and("authorId").is(user.getId()));
        List<ApCommentLike> likesList =  mongoTemplate.find(query1, ApCommentLike.class);
        List<ApCommentVo> apCommentVos = new ArrayList<>();
        if(list!=null && likesList!=null){
           list.stream().forEach(x->{
               ApCommentVo apCommentVo = new ApCommentVo();
               BeanUtils.copyProperties(x,apCommentVo);
               for (ApCommentLike apCommentLike : likesList) {
                   // 评论Id
                   if(apCommentLike.getCommentId() == x.getId()){
                       apCommentVo.setOperation((short)0);
                       break;
                   }
               }
               apCommentVos.add(apCommentVo);
           });
            return ResponseResult.okResult(apCommentVos);
        }else{
            return ResponseResult.okResult(list);
        }
    }
}
